﻿using System;
using System.Collections.Specialized;
using System.Threading;

using Eflong.Components;

namespace Eflong.Monitor
{
    internal class SaveRecordsTask
    {
        internal static SaveRecordsTask instance = null;

        internal static SaveRecordsTask Instance( )
        {
            if ( instance == null )
            {
                lock ( syncLock )
                {
                    if ( instance == null )
                    {
                        instance = new SaveRecordsTask( );
                    }
                }
            }
            return instance;
        }

        internal void Cleanup( )
        {
            if ( multiBackgroundWorker != null )
            {
                multiBackgroundWorker.Dispose( );
                multiBackgroundWorker = null;
            }
        }

        private SaveRecordsTask( )
        {
            InitMultiBackgroundWorker( );
        }

        internal HybridDictionary TaskDic { get; set; }

        /// <summary>
        /// 同步对象
        /// </summary>
        private static object syncLock = new object( );

        private static bool oneRun = false;

        /// <summary>
        /// 第一个正在运行，现在第二个正在等待
        /// </summary>
        private static bool otherRun = false;

        private static ManualResetEvent saveEvent = new ManualResetEvent( true );

        private MultiBackgroundWorker multiBackgroundWorker;

        private void InitMultiBackgroundWorker( )
        {
            multiBackgroundWorker = new MultiBackgroundWorker( );

            multiBackgroundWorker.ProgressChanged += new MultiProgressChangedEventHandler( multiBackgroundWorker_ProgressChanged );
            multiBackgroundWorker.RunWorkerCompleted += new MultiRunWorkerCompletedEventHandler( multiBackgroundWorker_RunWorkerCompleted );
            multiBackgroundWorker.DoWork += new MultiDoWorkEventHandler( multiBackgroundWorker_DoWork );
        }

        /// <summary>
        /// 开始一个新的保存任务
        /// </summary>
        internal void StartSaveRecords( )
        {
            lock ( syncLock )
            {
                if ( oneRun && otherRun )
                {
                    // 一个任务正在运行，且另一个正在等待，则返回
                    // 由于每次的执行都是逻辑上独立的，因此不需要重复执行
                    return;
                }
                if ( !oneRun )
                {
                    oneRun = true;
                }
                else
                {
                    otherRun = true;
                }
            }

            // Task IDs are Guids.
            string taskId = Guid.NewGuid( ).ToString( );

            TaskItem item = new TaskItem( ) { TaskId = taskId , StartTime = DateTime.Now , ProgressPercentage = 0 };
            TaskDic.Add( taskId , item );

            multiBackgroundWorker.RunWorkerAsync( taskId , null );
        }

        internal void CancleSaveRecords( string taskId )
        {
            multiBackgroundWorker.CancelAsync( taskId );
            TaskItem item = ( TaskItem )TaskDic[ taskId ];

            item.CompletedEventArgs = new MultiRunWorkerCompletedEventArgs( taskId , null , null , true );

            item.EndTime = DateTime.Now;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void multiBackgroundWorker_DoWork( object sender , MultiDoWorkEventArgs e )
        {
            int n = ( int )e.Argument;
            object taskId = e.TaskId;

            if ( oneRun && otherRun )
            {
                // 第一个运行，第二个等待，则返回
                return;
            }

            saveEvent.WaitOne( );

            e.Result = SaveRecords( n , taskId , ( MultiBackgroundWorker )sender , e );
            lock ( syncLock )
            {
                if ( oneRun )
                {
                    oneRun = false;
                }
                else
                {
                    otherRun = false;
                }
            }
            saveEvent.Set( );
        }

        private void multiBackgroundWorker_RunWorkerCompleted( object sender , MultiRunWorkerCompletedEventArgs e )
        {
            string taskId = ( string )e.TaskId;

            TaskItem item = ( TaskItem )TaskDic[ taskId ];

            item.CompletedEventArgs = e;
            item.EndTime = DateTime.Now;
        }

        private void multiBackgroundWorker_ProgressChanged( object sender , MultiProgressChangedEventArgs e )
        {
            string taskId = ( string )e.TaskId;

            TaskItem item = ( TaskItem )TaskDic[ taskId ];
            item.ProgressPercentage = e.ProgressPercentage;
        }

        /// <summary>
        /// 保存各种报警记录、故障记录、当前记录
        /// </summary>
        /// <param name="n"></param>
        /// <param name="taskId"></param>
        /// <param name="worker"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        private object SaveRecords( int n , object taskId , MultiBackgroundWorker worker , MultiDoWorkEventArgs e )
        {
            return null;
        }
    }
}